package com.freedom.rpc.thrift.common.extended;

import java.lang.reflect.Constructor;
import java.util.Set;

import org.apache.thrift.TMultiplexedProcessor;
import org.apache.thrift.TProcessor;
import org.reflections.Reflections;

import com.freedom.rpc.thrift.common.property.ServerProperties;
import com.freedom.rpc.thrift.common.annotation.Processor;
import com.freedom.rpc.thrift.common.utils.Logger;

public class ProcessorRegisterHelper {
	private static final Logger logger = Logger.getLogger(ProcessorRegisterHelper.class);
	private static final String SUFFIX = "$Iface";

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void registerProcessor(TMultiplexedProcessor processor) {
		// 切换成自动扫描方式
		try {
			// 扫描有注解Processor的类
			String scanPackage = ServerProperties.getInstance().getScanPackage();
			logger.info("scan package --- " + scanPackage);
			Reflections reflections = new Reflections(scanPackage);
			Set<Class<?>> annotationedClass = reflections.getTypesAnnotatedWith(Processor.class);
			logger.info("***|*** annotationedClass ---" + annotationedClass);
			for (Class implClz : annotationedClass) {
				logger.info("-----------------------------------------");
				logger.info("current class: " + implClz);
				// 开始查找这个类的接口名字
				Class[] interfaces = implClz.getInterfaces();
				Class interfaceClz = interfaces[0];
				logger.info("interface: " + interfaceClz);
				String interfaceClzName = interfaceClz.getName();// HelloWorldService$Iface
				logger.info("interfaceClzName:" + interfaceClzName);
				// 获取接口的包含类
				if (false == interfaceClzName.endsWith(SUFFIX)) {
					throw new Exception("interface clzName is not end with:" + SUFFIX);
				}
				String parentClzName = interfaceClzName.substring(0, interfaceClzName.length() - SUFFIX.length());
				logger.info("parent class: " + parentClzName);
				// 获取Processor类
				String processorClzName = parentClzName + "$Processor";
				logger.info("processor clz name:" + processorClzName);
				Class processorClz = Class.forName(processorClzName);
				// 实例化1
				Object ifaceInstance = (Object) implClz.newInstance();// new
				// HelloWorldServiceImpl()
				logger.info("generated : " + ifaceInstance);
				// 实例化2
				Class[] params = new Class[] { interfaceClz };
				Constructor constructor = processorClz.getConstructor(params);
				logger.info("constructor: " + constructor);
				TProcessor processorInstance = (TProcessor) constructor.newInstance(ifaceInstance);
				logger.info("generated:" + processorInstance);
				// 开始获取注解信息
				Processor annotation = (Processor) implClz.getAnnotation(Processor.class);
				String group = annotation.group();
				String service = annotation.service();
				String edition = annotation.edition();
				logger.info("detail: " + group + " " + service + " " + edition);
				//
				processor.registerProcessor(group + ":" + service + ":" + edition, processorInstance);
				logger.info("-----------------------------------------");
			}
		} catch (Exception e) {
			logger.error(e.toString());
			System.exit(-1);
		}
	}
}
